#ifndef ENGINE_H
#define ENGINE_H

#include <stdio.h>
#include "control.h"
#include "entity.h"
#include "file.h"
#include "main.h"
#include "menu.h"
#include "render.h"
#include "sound.h"
#include "timer.h"
#include "vga.h"

namespace VERGE1 {

    class Engine {
    public:
        Engine();
        virtual ~Engine();
        
        virtual File* fopen(const char* filename, const char* mode);
        virtual int fclose(File*& file);
        virtual int fscanf(File* file, const char* format, ...);
        virtual char* fgets(char* s, int n, File* file);
        virtual int fwrite(const void* p, int size, int count, File* file);
        virtual int remove(const char* filename);

        void InitPartyStats();
    };
    
    extern Engine engine;
}

struct r_entity {                      // on-screen entities (chars)
  unsigned short x;                    // xwc position
  unsigned short y;                    // ywc position
  unsigned char facing;                // direction entity is facing
  unsigned char moving;                // direction entity is moving
  unsigned char movcnt;                // how far left to move in this tile
  unsigned char framectr;              // frame sequence counter
  unsigned char specframe;             // special-frame set thingo
  unsigned char chrindex, movecode;    // CHR index / movement pattern code
  unsigned char activmode, obsmode;    // activation mode, obstruction mode
  unsigned int actscript, movescript;  // script references
  unsigned char speed, speedct;        // entity speed, speedcount :)
  unsigned short step, delay,          // Misc data entries
                 data1, data2,         // More misc data
                 data3, data4,         // yet more crappy misc data.
                 delayct,adjactv;      // yet more internal crap
  unsigned short x1,y1,x2,y2;          // bounding box coordinates
  unsigned char curcmd, cmdarg;        // Script commands/arguments
  unsigned char *scriptofs;            // offset in script parsing
  unsigned char face,chasing,          // face player when activated | chasing
                chasespeed, chasedist; // chasing variables
  unsigned short cx,cy;                // current-tile pos (moving adjusted)
  int expand1;                         // always room for improvement
  char entitydesc[20];                 // Editing description
};

struct zoneinfo {                      // zone data
  char zonename[15];                   // zone description
  unsigned short int callevent;        // event number to call
  unsigned char percent;               // chance (in 255) of event occurance
  unsigned char delay;                 // step-delay before last occurance
  unsigned char aaa;                   // accept adjacent activation
  char savedesc[30];                   // savegame description
};

struct charstats {                     // Stat record for single character
  char name[9];                        // 8-character name + null
  char chrfile[13];                    // CHR file for this character
  int exp, rea;                        // experience points, REAction
  int curhp, maxhp;                    // current/max hit points
  int curmp, maxmp;                    // current/max magic points
  int atk, def;                        // ATtacK and DEFense stats
  int str, end;                        // STRength and ENDurance
  int mag, mgr;                        // MAGic and MaGic Resistance stats
  int hit, dod;                        // HIT% and DODge%
  int mbl, fer;                        // MoBiLity and FERocity (not related)
  int magc, mgrc;                      // MAGic and MaGic Resistance stats
  int hitc, dodc;                      // HIT% and DODge%
  int mblc, ferc;                      // MoBiLity and FERocity (not related)
  int reac;                            // reaction (all ***c stats are current)
  int nxt, lv;                         // exp to next level, current level
  char status;                         // 0=fine 1=dead 2=...
  unsigned char invcnt;                // number of items in inventory
  unsigned short int inv[24];          // inventory

  // NEW: MAGIC VARIABLES

  unsigned char magcnt;                // number of items in inventory
  unsigned short int maginv[24];          // inventory

};

struct itemdesc {
  char name[20];              // item name
  unsigned short icon;             // icon index
  char desc[40];              // item description
  unsigned char useflag;               // Useable flag <see below>
  unsigned short useeffect;        // effect list index
  unsigned char itemtype;              // item type index
  unsigned char equipflag;             // 0=nonequipable 1=equipable
  unsigned char equipidx;              // equip.dat index value
  unsigned char itmprv;                // item preview code
  unsigned int price;                  // Cost of the item in a store
};

// NEW MAGIC

struct magicdesc {
  char name[20];              // magic name
  unsigned short icon;             // icon index
  char desc[40];              // magic description
  unsigned char useflag;               // Useable flag <see below>
  unsigned short int useeffect;        // magic effect list index
  unsigned char itemtype;              // magic type index
  unsigned char equipflag;             // 0=nonequipable 1=equipable
  unsigned char equipidx;              // magiceq.dat index value
  unsigned char itmprv;                // magic preview code
  
  // TODO: figure out what's needed here
  // engine.c had the following line only, instead of the two after it:
//unsigned int price;                  // Cost of the magic in a store
  unsigned int cost;                   // Cost of the magic in a store
  unsigned int price;                  // Cost of the magic to cast
};

// END NEW

struct equipstruc {
  int str,end,mag,mgr,hit,dod;
  int mbl,fer,rea;
  char equipable[30];
  char onequip, ondeequip;
};

struct vspanim {
    // start tile index
    unsigned short start;
    // end tile index
    unsigned short finish;
    // delay between cycles
    unsigned short delay;
    // animation mode
    unsigned short mode;
};

struct mequipstruc {
    char equipable[30];
    char level[30];
    char onequip;
    char ondeequip;
};

struct mstruct {
    int num;
    
    char name[9];                        // 8-character name + null
    char imgfile[13];                    // image file for this monster
    
    // Stats
    
    int curhp;
    int maxhp;
    int curmp;
    int maxmp;
    int atk;
    int def;
    int mag;
    int mdef;
    int agi;
    
    int other[10];
    
    int exp;
    int gold;
    
    // Display Options
    int x;
    int y;
};

// the party leader's last six moves
extern char lastmoves[6];
// current character-ref indexes
extern char partyidx[5];
// number of characters to draw
extern char numchars;
// tile animation data
extern struct vspanim va0[100];
// party entities
extern struct r_entity party[101];
// entity records
extern struct zoneinfo zone[128];
// party-stats record
extern struct charstats party_stats[30];
// item definition array
extern struct itemdesc items[255];

extern struct magicdesc magic[255];
// more graphic ptrs
extern unsigned char* magicicons;
// equipment definition array
extern struct mequipstruc mequip[255];

// equipment definition array
extern struct equipstruc equip[255];
extern char zonedelay;
// zone delay counter
extern char lz;
// total characters in PARTY.DAT
extern char tchars;
// party's gold (or meseta, s, $, etc)
extern int gp;

// delay counter
extern unsigned short vadelay[100];
// map data pointers
extern unsigned short* map0;
extern unsigned short* map1;
extern unsigned char* vsp0;
extern unsigned char* mapp;
// graphic data pointers
extern unsigned char* chrs;
extern unsigned char* itemicons;
extern unsigned char* chr2;
// misc flags
extern unsigned int flags[8000];

// file handles
extern FILE* map;
extern FILE* vsp;
// map filename
extern char mapname[13];
// music filename
extern char musname[13];
// vsp filename
extern char vsp0name[13];
// level name
extern char levelname[30];
// control flags
extern char layerc;
extern char showname;
extern char saveflag;

// window coordinates
extern int xwin;
extern int ywin;
extern int xtc;
extern int ytc;
extern int xofs;
extern int yofs;
// map dimensions
extern unsigned short xsize;
extern unsigned short ysize;
// default start location
extern unsigned short startx;
extern unsigned short starty;
// parallax speed X
extern unsigned char pmultx;
extern unsigned char pdivx;
// parallax speed X
extern unsigned char pmulty;
extern unsigned char pdivy;
// map warpable
extern char warp;
// hidable flags
extern char hide;

extern char dontshowname;
extern char usenxy;
extern char qabort;
extern char autoent;
extern unsigned short nx;
extern unsigned short ny;
extern unsigned short numtiles;

extern struct mstruct monsters[5];

extern char** mlist;

extern void allocbuffers();
extern void addcharacter(int i);
extern void LoadCHRList();
extern void load_map(char *fname);
extern void process_stepzone();
extern void lastmove(char n);
extern void startfollow();
extern int InvFace();
extern void Activate();
extern int ObstructionAt(int tx,int ty);
extern void process_entities();
extern void ProcessControls();
extern void process_controls();
extern void check_tileanimation();
extern void UpdateEquipStats();
extern void game_ai();
extern void CreateSaveImage(unsigned char *buf);
extern void SaveGame(char *fn);
extern void startmap(char *fname);

#endif
